{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.ensemble import IsolationForest\n",
    "import sys\n",
    "sys.path.append('../../common/')\n",
    "from evaluator import *\n",
    "import numpy as np\n",
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "def load_dataset(dataset, machine):\n",
    "    folder = os.path.join(\"../../processed\", dataset)\n",
    "    if not os.path.exists(folder):\n",
    "        raise Exception(\"Processed Data not found.\")\n",
    "    loader = []\n",
    "    for file in [\"train\", \"test\", \"labels\"]:\n",
    "        file = machine + \"_\" + file\n",
    "        loader.append(np.load(os.path.join(folder, f\"{file}.npy\")))\n",
    "    ## 准备数据\n",
    "    train_data = loader[0]\n",
    "    test_data = loader[1]\n",
    "    labels = np.zeros((loader[2].shape[0], 1))\n",
    "    for i, row in enumerate(loader[2]):\n",
    "        if np.any(row == 1):\n",
    "            labels[i] = 1   \n",
    "    return (train_data, test_data, labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## SMD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "total datas: 28\n"
     ]
    }
   ],
   "source": [
    "origin_file_list = os.listdir(\"../../data/SMD/interpretation_label\")\n",
    "file_name_list = []\n",
    "for origin_file in origin_file_list:\n",
    "    file_name_list.append(origin_file[:-4])\n",
    "file_name_list.sort()\n",
    "\n",
    "datas = {}\n",
    "for file_name in file_name_list:\n",
    "    train_data, test_data, labels = load_dataset(\"SMD\", file_name)\n",
    "    datas[file_name] = (train_data, test_data, labels)\n",
    "    # print(f\"train_data shape: {train_data.shape}\")\n",
    "    # print(f\"test_data shape: {test_data.shape}\")\n",
    "    # print(f\"labels shape: {labels.shape}\")\n",
    "print(f\"total datas: {len(datas)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "results = {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "for machine in file_name_list:\n",
    "        _,data, labels = datas[machine]\n",
    "        ratio = np.count_nonzero(labels == 1)/labels.shape[0]\n",
    "        model = IsolationForest(n_estimators=128, max_samples=4096,contamination=ratio, max_features=test_data.shape[1])  # contamination参数表示异常值的比例\n",
    "        model.fit(data)\n",
    "        predictions = model.predict(data)\n",
    "        y_pred =  np.where(predictions == -1, 1, 0)\n",
    "        y_pred = adjust_predicts(score=y_pred, label=labels, pred=y_pred)\n",
    "        p_t = calc_point2point(y_pred.squeeze(), labels.squeeze())\n",
    "        result = {\n",
    "                'f1-score': p_t[0],\n",
    "                'precision': p_t[1],\n",
    "                'recall': p_t[2],\n",
    "                'TP': p_t[3],\n",
    "                'TN': p_t[4],\n",
    "                'FP': p_t[5],\n",
    "                'FN': p_t[6]\n",
    "\n",
    "        }\n",
    "        results[machine] = result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "precision mean: 0.6398\n",
      "recall mean: 0.9954\n",
      "f1 mean: 0.7757\n",
      "f1* mean: 0.7789\n"
     ]
    }
   ],
   "source": [
    "f1_scores = [item['f1-score'] for item in list(results.values())]\n",
    "precisions = [item['precision'] for item in list(results.values())]\n",
    "recalls = [item['recall'] for item in list(results.values())]\n",
    "TNs = [item['TN'] for item in list(results.values())]\n",
    "TPs = [item['TP'] for item in list(results.values())]\n",
    "FNs = [item['FN'] for item in list(results.values())]\n",
    "FPs = [item['FP'] for item in list(results.values())]\n",
    "f1_mean = round(np.mean(f1_scores).item(),4)\n",
    "precision_mean = round(np.mean(precisions),4)\n",
    "recall_mean = round(np.mean(recalls),4)\n",
    "f1_star = round(2 * precision_mean * recall_mean / (precision_mean + recall_mean + 0.00001),4)\n",
    "print(f\"precision mean: {precision_mean}\")\n",
    "print(f\"recall mean: {recall_mean}\")\n",
    "print(f\"f1 mean: {f1_mean}\")\n",
    "print(f\"f1* mean: {f1_star}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## SMAP"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "origin_file_list = os.listdir(\"../../processed/SMAP\")\n",
    "file_name_set = set()\n",
    "for origin_file in origin_file_list:\n",
    "    file_name_set.add(origin_file.split(\"_\")[0])\n",
    "file_name_list = list(file_name_set)\n",
    "file_name_list.sort()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "datas = {}\n",
    "for file_name in file_name_list:\n",
    "    train_data, test_data, labels = load_dataset(\"SMAP\", file_name)\n",
    "    datas[file_name] = (train_data, test_data, labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "results = {}\n",
    "for machine in file_name_list:\n",
    "        _,data, labels = datas[machine]\n",
    "        ratio = np.count_nonzero(labels == 1)/labels.shape[0]\n",
    "        model = IsolationForest(n_estimators=128, max_samples=1024,contamination=ratio, max_features=test_data.shape[1])  # contamination参数表示异常值的比例\n",
    "        model.fit(data)\n",
    "        predictions = model.predict(data)\n",
    "        y_pred =  np.where(predictions == -1, 1, 0)\n",
    "        y_pred = adjust_predicts(score=y_pred, label=labels, pred=y_pred)\n",
    "        p_t = calc_point2point(y_pred.squeeze(), labels.squeeze())\n",
    "        result = {\n",
    "                'f1-score': p_t[0],\n",
    "                'precision': p_t[1],\n",
    "                'recall': p_t[2],\n",
    "                'TP': p_t[3],\n",
    "                'TN': p_t[4],\n",
    "                'FP': p_t[5],\n",
    "                'FN': p_t[6]\n",
    "\n",
    "        }\n",
    "        results[machine] = result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "precision mean: 0.5122\n",
      "recall mean: 0.797\n",
      "f1 mean: 0.617\n",
      "f1* mean: 0.6236\n"
     ]
    }
   ],
   "source": [
    "f1_scores = [item['f1-score'] for item in list(results.values())]\n",
    "precisions = [item['precision'] for item in list(results.values())]\n",
    "recalls = [item['recall'] for item in list(results.values())]\n",
    "TNs = [item['TN'] for item in list(results.values())]\n",
    "TPs = [item['TP'] for item in list(results.values())]\n",
    "FNs = [item['FN'] for item in list(results.values())]\n",
    "FPs = [item['FP'] for item in list(results.values())]\n",
    "f1_mean = round(np.mean(f1_scores).item(),4)\n",
    "precision_mean = round(np.mean(precisions),4)\n",
    "recall_mean = round(np.mean(recalls),4)\n",
    "f1_star = round(2 * precision_mean * recall_mean / (precision_mean + recall_mean + 0.00001),4)\n",
    "print(f\"precision mean: {precision_mean}\")\n",
    "print(f\"recall mean: {recall_mean}\")\n",
    "print(f\"f1 mean: {f1_mean}\")\n",
    "print(f\"f1* mean: {f1_star}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## MSL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "origin_file_list = os.listdir(\"../../processed/MSL\")\n",
    "file_name_set = set()\n",
    "for origin_file in origin_file_list:\n",
    "    file_name_set.add(origin_file.split(\"_\")[0])\n",
    "file_name_list = list(file_name_set)\n",
    "file_name_list.sort()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "datas = {}\n",
    "for file_name in file_name_list:\n",
    "    train_data, test_data, labels = load_dataset(\"MSL\", file_name)\n",
    "    datas[file_name] = (train_data, test_data, labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "results = {}\n",
    "for machine in file_name_list:\n",
    "        _,data, labels = datas[machine]\n",
    "        ratio = np.count_nonzero(labels == 1)/labels.shape[0]\n",
    "        ratio = ratio if ratio < 0.5 else 0.5\n",
    "        model = IsolationForest(n_estimators=128, max_samples=1024,contamination=ratio, max_features=test_data.shape[1])  # contamination参数表示异常值的比例\n",
    "        model.fit(data)\n",
    "        predictions = model.predict(data)\n",
    "        y_pred =  np.where(predictions == -1, 1, 0)\n",
    "        y_pred = adjust_predicts(score=y_pred, label=labels, pred=y_pred)\n",
    "        p_t = calc_point2point(y_pred.squeeze(), labels.squeeze())\n",
    "        result = {\n",
    "                'f1-score': p_t[0],\n",
    "                'precision': p_t[1],\n",
    "                'recall': p_t[2],\n",
    "                'TP': p_t[3],\n",
    "                'TN': p_t[4],\n",
    "                'FP': p_t[5],\n",
    "                'FN': p_t[6]\n",
    "\n",
    "        }\n",
    "        results[machine] = result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "precision mean: 0.5444\n",
      "recall mean: 0.9436\n",
      "f1 mean: 0.689\n",
      "f1* mean: 0.6904\n"
     ]
    }
   ],
   "source": [
    "f1_scores = [item['f1-score'] for item in list(results.values())]\n",
    "precisions = [item['precision'] for item in list(results.values())]\n",
    "recalls = [item['recall'] for item in list(results.values())]\n",
    "TNs = [item['TN'] for item in list(results.values())]\n",
    "TPs = [item['TP'] for item in list(results.values())]\n",
    "FNs = [item['FN'] for item in list(results.values())]\n",
    "FPs = [item['FP'] for item in list(results.values())]\n",
    "f1_mean = round(np.mean(f1_scores).item(),4)\n",
    "precision_mean = round(np.mean(precisions),4)\n",
    "recall_mean = round(np.mean(recalls),4)\n",
    "f1_star = round(2 * precision_mean * recall_mean / (precision_mean + recall_mean + 0.00001),4)\n",
    "print(f\"precision mean: {precision_mean}\")\n",
    "print(f\"recall mean: {recall_mean}\")\n",
    "print(f\"f1 mean: {f1_mean}\")\n",
    "print(f\"f1* mean: {f1_star}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "yjq-ml",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
